{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5c5139a0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<PyDISPLAY_DEVICE at 0x1cc957f3260>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import win32api\n",
    "win32api.EnumDisplayDevices()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2cf70374",
   "metadata": {},
   "outputs": [],
   "source": [
    "import win32gui\n",
    "current_window = win32gui.GetForegroundWindow()\n",
    "print (current_window)\n",
    "current_window_name = win32gui.GetClassName(current_window)\n",
    "print (current_window_name)\n",
    "current_window_tilte = win32gui.GetWindowText(current_window)\n",
    "print (current_window_tilte)\n",
    "win32gui.SetWindowPos?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "id": "078d0929",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "E:\\git\\blog\\python\\examples\n",
      "j2-1str\n",
      "{\"j1\": \"rewirte_str\", \"j2\": {\"j2-1\": \"j2-1str\"}}\n"
     ]
    }
   ],
   "source": [
    "import json\n",
    "import os\n",
    "print (os.getcwd())\n",
    "os.listdir(os.getcwd())\n",
    "with open('rw_json.json','w') as f:\n",
    "    f.write('{\"j1\":2,\"j2\":{\"j2-1\":\"j2-1str\"}}')\n",
    "with open('rw_json.json','r') as f:\n",
    "    j = json.load(f)\n",
    "print (j[\"j2\"][\"j2-1\"])\n",
    "j[\"j1\"]=\"rewirte_str\"\n",
    "sj=json.dumps(j)\n",
    "print (sj)\n",
    "with open('rw_json.json','wt') as f:\n",
    "    json.dump(sj,f) # ouput:\"{\\\"j1\\\": \\\"rewirte_str\\\", \\\"j2\\\": {\\\"j2-1\\\": \\\"j2-1str\\\"}}\"\n",
    "\n",
    "json.dumps?\n",
    "with open('rw_json.json','wt') as f:\n",
    "    f.write(json.dumps(j))\n",
    "    # f.close()\n",
    "# json.dump(j){\"j1\":2,\"j2\":{\"j2-1\":\"j2-1str\"}}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "03305b03",
   "metadata": {},
   "outputs": [],
   "source": [
    "def show(self):\n",
    "    # windows handlers\n",
    "    hwnd = self.window.handle\n",
    "    win32gui.SetForegroundWindow (hwnd)\n",
    "    win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0,0,0,0, win32con.SWP_NOMOVE | win32con.SWP_NOACTIVATE| win32con.SWP_NOOWNERZORDER|win32con.SWP_SHOWWINDOW)\t\n",
    "    X11LockScreenWindow.show(self)\n",
    "    \n",
    "def hide(self):\n",
    "    X11LockScreenWindow.hide(self)\n",
    "    # windows handlers\n",
    "    hwnd = self.window.handle\n",
    "    win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0,0,0,0,win32con.SWP_HIDEWINDOW|win32con.SWP_NOMOVE|win32con.SWP_NOSIZE|win32con.SWP_NOACTIVATE|win32con.SWP_NOOWNERZORDER)\n",
    "\n",
    "X11LockScreenWindow?\n",
    "%history"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "id": "760771b4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "import win32gui, win32con\n",
    "import sys\n",
    "windows_list = []\n",
    "# 获取所有窗口\n",
    "win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), windows_list)\n",
    "\n",
    "for window in windows_list:\n",
    "    # 获取窗口类和标题\n",
    "    classname = win32gui.GetClassName(window)\n",
    "    title = win32gui.GetWindowText(window)\n",
    "#     print(f'classname:{classname} title:{title}')\n",
    "    if title.__eq__('任务管理器'):\n",
    "#         print(f'classname:{classname} title:{title}')\n",
    "        # 判断窗口是否可见\n",
    "        bVisible = win32gui.IsWindowVisible(window)\n",
    "        if bVisible == 0:\n",
    "            raise SystemExit(\"{title}窗口不可见\")\n",
    "        # 将最小化的可见窗口展示到前台\n",
    "        win32gui.ShowWindow(window, win32con.SW_SHOWNORMAL)\n",
    "        '''\n",
    "            SetForegroundWindow将创建指定窗口的线程引入前台并激活窗口。 键盘输入将定向到窗口。\n",
    "            当使用另一个窗口时，无法将窗口强制到前台。且窗口应用程序可拒绝其他进程调用\n",
    "        '''\n",
    "#         win32gui.SetForegroundWindow (window)\n",
    "        '''\n",
    "            **注意：SetWindowPos无法激活非活动窗口，设置窗口顺序，拥有该窗口的进程必须具有 SetForegroundWindow 权限。**\n",
    "            \n",
    "            win32con.HWND_TOPMOST,将窗口置顶，即使未获取焦点仍置顶并保持（即强制获取SetForegroundWindow 权限），使用win32con.HWND_NOTOPMOST取消\n",
    "            win32con.HWND_TOP，将窗口置于 Z 顺序的顶部\n",
    "            win32con.SWP_NOMOVE，保留当前位置 (忽略 X 和 Y 参数，第3和第4位置参数) \n",
    "            win32con.SWP_NOSIZE，保留当前大小 (忽略 cx 和 cy 参数，第5和第6位置参数) \n",
    "            win32con.SWP_SHOWWINDOW，显示“接收端口跟踪选项” 窗口。\n",
    "            win32con.SWP_NOACTIVATE，不激活窗口。 如果未设置此标志，则会激活窗口\n",
    "        '''\n",
    "#         b = win32gui.SetWindowPos(window, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE |\n",
    "#                                   win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW | (win32con.SWP_NOACTIVATE if bVisible != 0 else 0))\n",
    "#         win32gui.SetWindowPos(window, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE |\n",
    "#                                   win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW | (win32con.SWP_NOACTIVATE if bVisible != 0 else 0))\n",
    "        win32gui.SetWindowPos(window, win32con.HWND_TOP, 0, 0, 0, 0, win32con.SWP_NOMOVE |\n",
    "                                  win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW | (win32con.SWP_NOACTIVATE if bVisible != 0 else 0))\n",
    "        print (b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "f5246064",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(Namespace(), ['-f', 'C:\\\\Users\\\\USER\\\\AppData\\\\Roaming\\\\jupyter\\\\runtime\\\\kernel-54dd2c40-9fd1-4546-9035-0d7ba2197752.json'])\n",
      "Namespace() ---- ['-f', 'C:\\\\Users\\\\USER\\\\AppData\\\\Roaming\\\\jupyter\\\\runtime\\\\kernel-54dd2c40-9fd1-4546-9035-0d7ba2197752.json']\n",
      "(Namespace(), ['-f', 'C:\\\\Users\\\\USER\\\\AppData\\\\Roaming\\\\jupyter\\\\runtime\\\\kernel-54dd2c40-9fd1-4546-9035-0d7ba2197752.json'])\n"
     ]
    }
   ],
   "source": [
    "import argparse\n",
    "# , and add port for a existing container\n",
    "parser = argparse.ArgumentParser(description='Change docker config file(hostconfig.json or config.v2.json)')\n",
    "# 添加需要处理的文件名列表,相对路径获取文件\n",
    "# parser.add_argument(dest='filenames',metavar='filename', nargs='*', help='please input relative path')\n",
    "# parser.add_argument('-p', '--ports',metavar='host_port:container_port',  dest='ports', action='append', help='need add port map')\n",
    "# parser.add_argument('--speed', dest='speed', action='store', choices={'slow','fast'}, default='slow', help='search speed')required=True,\n",
    "# parser.add_argument('others', nargs=argparse.REMAINDER)\n",
    "# args = parser.parse_args()\n",
    "args = parser.parse_known_args()\n",
    "args2, unknown = parser.parse_known_args()\n",
    "args3 = parser.parse_known_intermixed_args()\n",
    "# print (args.filenames)\n",
    "# print (args.ports)\n",
    "print (args)\n",
    "print (args2,'----',unknown)\n",
    "print (args3)\n",
    "# parser.parse_known_args?\n",
    "# docker 容器添加端口的python脚本\n",
    "# def get_file_content_json():\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "9f86b9cc",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "incomplete input (641422499.py, line 31)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  Cell \u001b[1;32mIn[16], line 31\u001b[1;36m\u001b[0m\n\u001b[1;33m    if __name__ == '__main__':\u001b[0m\n\u001b[1;37m                              ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m incomplete input\n"
     ]
    }
   ],
   "source": [
    "import argparse, os, json\n",
    "# , and add port for a existing container\n",
    "\n",
    "\n",
    "# parser.parse_known_args?\n",
    "# docker 容器添加端口的python脚本\n",
    "def get_or_set_file_content_json(file_path, model = 'r',content_json_str = None):\n",
    "    if model.__eq__('w') and content_json_str != None:\n",
    "        with open(os.path.join( os.path.dirname(__file__), file_path), 'wt') as f:\n",
    "            f.write(content_json_str)\n",
    "        return\n",
    "    elif model.__eq__('w') and content_json_str == None:\n",
    "        raise SystemExit('写配置文件未传入参数')\n",
    "    with open(os.path.join( os.path.dirname(__file__), file_path), 'rt') as f:\n",
    "        file_content_json = json.load(f)\n",
    "    return file_content_json\n",
    "'''\n",
    "在hostconfig.json配置文件中添加映射端口\n",
    "如果PortBindings不存在，则创建。存在则判断容器端口是否已映射\n",
    "已映射，则添加映射规则，无创建\n",
    "'''\n",
    "def handle_add_port_config(file_content_json: dict, container_port_config: dict):\n",
    "    # PortBindings不存在,创建PortBindings\n",
    "    port_bindings = file_content_json.setdefault('PortBindings', {})\n",
    "#     and isinstance(port_bindings, dict)\n",
    "    # 将需要处理的容器映射端口container_port_config，添加入PortBindings项\n",
    "    for key in container_port_config:\n",
    "        # PortBindings子项容器映射端口不存在,创建\n",
    "        port_bindings_key = port_bindings.setdefault(key, [])\n",
    "        if len([n for n in port_bindings_key if n in container_port_config[key]]) != 0:\n",
    "            raise SystemExit('添加端口映射已存在')\n",
    "        port_bindings_key.extend(container_port_config[key])\n",
    "    return file_content_json\n",
    "#     file_content_json['PortBindings'] = {}\n",
    "#     port_bindings = file_content_json['PortBindings']\n",
    "#     port_bindings[container_port]\n",
    "    \n",
    "# 得到需要添加的映射端口选项\n",
    "def get_need_container_port_info(container_port, host_port):\n",
    "    container_port_str = container_port + '/' + args.protocol\n",
    "    host_port_dict = {}\n",
    "    host_port_dict['HostIp'] = ''\n",
    "    host_port_dict['HostPort'] = str(host_port)\n",
    "    return {str(container_port_str): [host_port_dict]}\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    parser = argparse.ArgumentParser(description='Change docker config file(hostconfig.json or config.v2.json)')\n",
    "    # 添加需要处理的文件名列表,相对路径获取文件\n",
    "    parser.add_argument(dest='filenames',metavar='filename', nargs='*', help='please input relative path')\n",
    "    parser.add_argument('-p', '--ports',metavar='host_port:container_port',  dest='map_ports', action='append', help='need add port map')\n",
    "    parser.add_argument('--protocol', dest='protocol', action='store', choices={'tcp','udp'}, \n",
    "                        default='tcp', help='select protocol default tcp')\n",
    "\n",
    "    args, unknown = parser.parse_known_args()\n",
    "    \n",
    "    for port_map in args.map_ports:\n",
    "        container_port, host_port = port_map.split(':')\n",
    "        # 获取容器需要配置项\n",
    "        container_port_config = get_need_container_port_info( container_port, host_port)\n",
    "        print (container_port_config)\n",
    "        for file in args.filenames:\n",
    "            # 添加配置\n",
    "            file_content_json = handle_add_port_config(get_or_set_file_content_json(file), container_port_config)\n",
    "            get_or_set_file_content_json(file, 'w', json.dumps(file_content_json))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "ab1f8b10",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "23 45\n",
      "{'as': 1, 'sed': {'gtesd2': 4}}\n",
      "<class 'dict'>\n",
      "True\n",
      "dict_keys([]) 0\n",
      "8000/tcp None\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'D:\\\\Anaconda3\\\\Anaconda\\\\Lib\\\\json\\\\__init__.py'"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import json\n",
    "# print (':'.join(\"23:45\"))\n",
    "container_port, host_port = \"23:45\".split(':')\n",
    "print (container_port, host_port)\n",
    "content_json = ''\n",
    "js='{\"as\":1}'\n",
    "jo = json.loads(js)\n",
    "gtesd=jo.setdefault('sed',{})\n",
    "gtesd['gtesd2']=4\n",
    "print (jo)\n",
    "print (type(jo))\n",
    "# print (isinstance(content_json, json))\n",
    "content_json = \"xs\"\n",
    "\n",
    "print (content_json!=None)\n",
    "file_content_json = {}\n",
    "port_bindings = file_content_json.keys()\n",
    "print (port_bindings, len(port_bindings))\n",
    "c={'8000/tcp': [{'HostIp': '', 'HostPort': '8000'}]}\n",
    "for k in c:\n",
    "    print (k,c[k].append({'HostIp': '', 'HostPort': '8000'}))\n",
    "#     print ()\n",
    "json.__file__\n",
    "# help([].append)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
